package com.cc.lambda;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * @Author C.
 * @Date 2019-03-31 12:28
 * <p>
 * <p>
 * java.util.function中 Function, Supplier, Consumer, Predicate和其他函数式接口广泛用在支持lambda表达式的API中。
 * 这些接口有一个抽象方法，会被lambda表达式的定义所覆盖。
 * Consumer的作用顾名思义,是给定义一个参数,对其进行(消费)处理,处理的方式可以是任意操作.
 */
public class ConsumerTest {
    /**
     * 其核心方法如下:
     * void accept(T t);
     * 对给定的参数T执行定义的操作
     * <p>
     * default Consumer<T> andThen(Consumer<? super T> after)
     * 对给定的参数T执行定义的操作执行再继续执行after定义的操作
     * <p>
     * 下面代码将给定的一批用户里面的名称为"lisi"的用户都给打包起来
     */
    @Test
    public void test_accept() {
        List<Person> lisiList = new ArrayList<>();
        Consumer<Person> consumer = x -> {
            if (x.name.equals("lisi")) {
                lisiList.add(x);
            }
        };
        Stream.of(
                new Person(21, "zhangsan"),
                new Person(22, "lisi"),
                new Person(23, "wangwu"),
                new Person(24, "wangwu"),
                new Person(23, "lisi"),
                new Person(26, "lisi"),
                new Person(26, "zhangsan")
        ).forEach(consumer);
        System.out.println(lisiList);
    }

    /**
     * 将给定的一批用户里面的名称为"lisi"且年龄大于22岁的用户都给打包起来
     */
    @Test
    public void test_andThen() {
        List<Person> lisiList = new ArrayList<>();
        Consumer <Person> consumer  =  x -> {
            if (x.name.equals("lisi")){
                lisiList.add(x);
            }
        };

        consumer = consumer.andThen(
                x -> lisiList.removeIf(y -> y.age < 23)
        );

        Stream.of(
                new Person(21,"zhangsan"),
                new Person(22,"lisi"),
                new Person(23,"wangwu"),
                new Person(24,"wangwu"),
                new Person(23,"lisi"),
                new Person(26,"lisi"),
                new Person(26,"zhangsan")
        ).forEach(consumer);

        System.out.println(lisiList);
    }

    /**
     * 与Consumer<T>相关的接口
     * BiConsumer<T, U>
     *     处理一个两个参数
     * DoubleConsumer
     *     处理一个double类型的参数
     * IntConsumer
     *     处理一个int类型的参数
     * LongConsumer
     *     处理一个long类型的参数
     * ObjIntConsumer<T>
     *     处理两个两个参数,且第二个参数必须为int类型
     * ObjLongConsumer<T>
     *     处理两个两个参数,且第二个参数必须为long类型
     */
}

class Person {
    String name;
    Integer age;

    Person(Integer age, String name) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}